﻿/*
  CTexture2DDDD3D.cpp 和 CSkyCubeTextureDDD3D.cpp 共同須要的函數
*/

#include <Sys\RenderUnit\SysDatagramDisposal_D3D\STAGEDDD3D9.HPP>
#include <Sys\MATRIX.HPP>
#include <Sys\CSMART_PTR.HPP>
#include <d3dx9.h>

using namespace CxxlMan;
using namespace Cxxl3D;


// 自動產生貼圖座標
// 參數以 D3D9 的 D3DTSS_TCI 為功能基準
// 0:以頂點在 View 座標系中的 x,y 值作為貼圖的 u,v，頂點的 z 值不使用，內定值(CAMERASPACEPOSITION)
// 1:以頂點在 View 座標系中的 法向量值 作為貼圖的座標值(CAMERASPACENORMAL)
// 2:以 反射向量值 作為貼圖的座標值，其值在 View 座標系中的頂點位置和法向量來計算(CAMERASPACEREFLECTIONVECTOR)
// 3:以頂點在 View 座標系中 法向量的 x,y 值轉換到 [0,1] 區間，作為貼圖的座標值(SPHEREMAP)
// -1:不使用自動產生貼圖座標
bool cxxlFASTCALL AutoTexCoordIndexMode(char Mode,LPDIRECT3DDEVICE9 pDEVICE9, const Smart_Ptr<IStageDDD3D9> IStageDDD3D9_Arg)
{    
  switch(Mode)
  {
  case 0:
      pDEVICE9->SetTextureStageState(IStageDDD3D9_Arg->GetStage(), D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
      return true;
      break;
  case 1:
      pDEVICE9->SetTextureStageState(IStageDDD3D9_Arg->GetStage(), D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACENORMAL);
      return true;
      break;
  case 2:
      pDEVICE9->SetTextureStageState(IStageDDD3D9_Arg->GetStage(), D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
      return true;
      break;
  case 3:
      pDEVICE9->SetTextureStageState(IStageDDD3D9_Arg->GetStage(), D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_SPHEREMAP);
      return true;
      break;
  case -1:
      pDEVICE9->SetTextureStageState(IStageDDD3D9_Arg->GetStage(), D3DTSS_TEXCOORDINDEX, 0);
      return true;
  }

  return false;
}


// 設定貼圖座標模式 Mode = 0:Repeat 1:Mirror 2:ClampEdge 3:ClampBorder
// Mode 指定為 ClampBorder 時，RGBA 指定所用的顏色，內定為 0,0,0,0                       
void TextureAddrMode(unsigned char Mode, unsigned int RGBA, LPDIRECT3DDEVICE9 pDEVICE9, const Smart_Ptr<IStageDDD3D9> IStageDDD3D9_Arg)
{
  D3DTEXTUREADDRESS mode;
  const char *_RGBA = (const char*)&RGBA;

  switch(Mode)
  {
  case 0:
    mode = D3DTADDRESS_WRAP;
    break;
  case 1:
    mode = D3DTADDRESS_MIRROR;
    break;
  case 2:
    mode = D3DTADDRESS_CLAMP;
    break;
  case 3:
    mode = D3DTADDRESS_BORDER;
    pDEVICE9->SetSamplerState(IStageDDD3D9_Arg->GetStage(), D3DSAMP_BORDERCOLOR, D3DCOLOR_RGBA(_RGBA[0],_RGBA[1],_RGBA[2],_RGBA[3]));
    break;
  }
  pDEVICE9->SetSamplerState(IStageDDD3D9_Arg->GetStage(), D3DSAMP_ADDRESSU, mode);
  pDEVICE9->SetSamplerState(IStageDDD3D9_Arg->GetStage(), D3DSAMP_ADDRESSV, mode);
}

// 貼圖的 Mipmap 模式 Mode = 0:None 1:Bilinear 2:Trilinear 3:Anisotropic filter
void TextureMipmapMode(unsigned char Mode, LPDIRECT3DDEVICE9 pDEVICE9, const Smart_Ptr<IStageDDD3D9> IStageDDD3D9_Arg)
{
  switch(Mode)
  {
  case 0:
      // 貼圖被放大時, 取最接近4個點來內插
      pDEVICE9->SetSamplerState(IStageDDD3D9_Arg->GetStage(), D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
      // 貼圖被縮小時, 取最接近4個點來平均
      pDEVICE9->SetSamplerState(IStageDDD3D9_Arg->GetStage(), D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
      // 不使用Mipmap
	    pDEVICE9->SetSamplerState(IStageDDD3D9_Arg->GetStage(), D3DSAMP_MIPFILTER, D3DTEXF_NONE);
      break;
  case 1:
      // 貼圖被放大時, 取最接近4個點來內插
      pDEVICE9->SetSamplerState(IStageDDD3D9_Arg->GetStage(), D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
      // 貼圖被縮小時, 取最接近4個點來平均
      pDEVICE9->SetSamplerState(IStageDDD3D9_Arg->GetStage(), D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
      // 取最接近大小的圖層
      pDEVICE9->SetSamplerState(IStageDDD3D9_Arg->GetStage(), D3DSAMP_MIPFILTER, D3DTEXF_POINT);
      break;
  case 2:
      // 貼圖被放大時, 取最接近4個點來內插
      pDEVICE9->SetSamplerState(IStageDDD3D9_Arg->GetStage(), D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
      // 貼圖被縮小時, 取最接近4個點來平均
      pDEVICE9->SetSamplerState(IStageDDD3D9_Arg->GetStage(), D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
      // 取最接近大小的兩個圖層, 然後再內插
      pDEVICE9->SetSamplerState(IStageDDD3D9_Arg->GetStage(), D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
      break;
  case 3:
      // 會根據縮放的長寬比例來取用貼圖, 不固定是取哪幾個圖
      pDEVICE9->SetSamplerState(IStageDDD3D9_Arg->GetStage(), D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
      pDEVICE9->SetSamplerState(IStageDDD3D9_Arg->GetStage(), D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC);
      pDEVICE9->SetSamplerState(IStageDDD3D9_Arg->GetStage(), D3DSAMP_MAXANISOTROPY, 8);
      // 取最接近大小的兩個圖層, 然後再內插
      pDEVICE9->SetSamplerState(IStageDDD3D9_Arg->GetStage(), D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
  }
}

void cxxlFASTCALL BlendMode(unsigned char BlendMode, LPDIRECT3DDEVICE9 pDEVICE9, const Smart_Ptr<IStageDDD3D9> IStageDDD3D9_Arg)
{
  switch(BlendMode)
  {
  case 1:      
      pDEVICE9->SetTextureStageState(IStageDDD3D9_Arg->GetStage(), D3DTSS_COLOROP, D3DTOP_SELECTARG1);
      pDEVICE9->SetTextureStageState(IStageDDD3D9_Arg->GetStage(), D3DTSS_COLORARG1, D3DTA_TEXTURE);
      pDEVICE9->SetTextureStageState(IStageDDD3D9_Arg->GetStage(), D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
      pDEVICE9->SetTextureStageState(IStageDDD3D9_Arg->GetStage(), D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
      break;
  case 2:      
      pDEVICE9->SetTextureStageState(IStageDDD3D9_Arg->GetStage(), D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
      pDEVICE9->SetTextureStageState(IStageDDD3D9_Arg->GetStage(), D3DTSS_COLORARG1, D3DTA_TEXTURE);
      pDEVICE9->SetTextureStageState(IStageDDD3D9_Arg->GetStage(), D3DTSS_COLORARG2, D3DTA_CURRENT);
      pDEVICE9->SetTextureStageState(IStageDDD3D9_Arg->GetStage(), D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
      pDEVICE9->SetTextureStageState(IStageDDD3D9_Arg->GetStage(), D3DTSS_ALPHAARG2, D3DTA_CURRENT);      
      break;
  default:
      pDEVICE9->SetTextureStageState(IStageDDD3D9_Arg->GetStage(), D3DTSS_COLOROP, D3DTOP_MODULATE); 
      pDEVICE9->SetTextureStageState(IStageDDD3D9_Arg->GetStage(), D3DTSS_COLORARG1, D3DTA_CURRENT);
      pDEVICE9->SetTextureStageState(IStageDDD3D9_Arg->GetStage(), D3DTSS_COLORARG2, D3DTA_TEXTURE);
      pDEVICE9->SetTextureStageState(IStageDDD3D9_Arg->GetStage(), D3DTSS_ALPHAOP, D3DTOP_MODULATE);
      pDEVICE9->SetTextureStageState(IStageDDD3D9_Arg->GetStage(), D3DTSS_ALPHAARG1, D3DTA_CURRENT);
      pDEVICE9->SetTextureStageState(IStageDDD3D9_Arg->GetStage(), D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
  };
}

